鼠年全馬鐵人挑戰 - WEEK 19
前言
目前正在進行一個Side Project,用朋友開給我的虛擬機(VM)架設一台API Server,趁還有記憶時趕快來筆記一下。
前置作業:
- OS: Ubuntu 18.04
- Web Framework: Django 3.0; djangorestframework 3.11
- Server: Nginx 1.14
- Database: MySQL
實作
架構圖如下:
安裝環境
安裝所需要的環境,會下載python3、mysql、nginx
1 2
| sudo apt-get update sudo apt-get install python3-pip python3-dev mysql-server libmysqlclient-dev nginx
|
資料庫
1 2
| sudo mysql_install_db sudo mysql_secure_installation
|
執行上述指令進行初始化,系統會詢問一些相關設定,可以全部都採預設的方式。其中,要設定root權限的密碼,設定完之後執行下方指令登入root帳號
完成登入便會進入MySQL Shell,在Shell中寫下腳本建立資料庫
1
| CREATE DATABASE <yourprojectname> CHARACTER SET UTF8;
|
將上述的<yourprojectname>
替換成自己要建立的資料庫名稱,其中utf8
為Django預設得編碼。
接著是在MySQL中建立另一個User,建議之後都使用User的帳號來登入資料庫!
1
| CREATE USER <yourdbuser>@localhost IDENTIFIED BY '<password>';
|
上述指令中,<yourdbuser>
為自訂的User名稱,<password>
為自訂的密碼,注意密碼要以字串的形式撰寫(要有''
)。
1
| GRANT ALL PRIVILEGES ON <yourprojectname>.* TO <yourdbuser>@localhost;
|
執行上述指令,賦予剛建立的User訪問資料庫的權限。
專案
下載相依套件
1 2
| sudo -H pip3 install --upgrade pip sudo -H pip3 install virtualenv
|
如果先前在Github上的repo已經有專案,可以直接Clone到Ubuntu的環境中
或是直接在Ubuntu中建立新的專案
1 2
| mkdir ~/<yourprojectdir> cd ~/<yourprojectdir>
|
在專案資料夾中建立虛擬環境
啟動虛擬環境
1
| source <yourenv>/bin/activate
|
以我為例,我的虛擬環境名稱為env
啟動虛擬環境後會看到終端機的最左方有的(env)
表示啟動虛擬環境,若要退出虛擬環境則執行deactive
。
下載專案所需的相依套件
1
| pip3 install django gunicorn pymysql djangorestframework
|
建立Django restframework的手把手教學可以參考官網範例。
本文是直接Clone之前已經在Github建立好的Repo,建立Django專案的部分便不多加詳述,主要是紀錄部署到實際環境需要修改的設定。
到Django主要專案的資料夾下,建立一個名為__init__.py
的檔案
寫下下方程式碼
__init__.py
1 2 3
| import pymysql pymysql.version_info = (1, 3, 13, "final", 0) pymysql.install_as_MySQLdb()
|
寫完上述程式碼後儲存離開ESC
+:wq!
接著在settings.py
中做下方幾個更改
settings.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ALLOWED_HOSTS = [ 'domain.com', '<yourserverip>', 'localhost']
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '<yourdatabasename>', 'USER': '<yourdbuser>', 'PASSWORD': '<password>', 'HOST': 'localhost', 'PORT': '3306', } }
STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
|
寫完上述程式碼後儲存離開ESC
+:wq!
ALLOWED_HOSTS
為網域名稱、IP,還有設定連接Mysql資料庫,輸入剛才前面設定資料時,建立的資料庫名稱、使用者帳號、密碼。最後是STATIC_ROOT
為設定靜態資源的根路徑。
執行
1
| python3 manage.py collectstatic
|
執行下方指令進行資料庫遷移
1 2
| python3 manage.py makemigrations python3 manage.py migrate
|
gunicorn
使用gunicorn測試Server
1 2
| cd ~/<yourprojectdir> gunicorn --bind 0.0.0.0:8000 <yourproject>.wsgi
|
成功後會看到下方畫面
接著訪問你的伺服器IP加上Port號即可查看目前運作狀況,如xxx.xxx.xx.xx:8000
。
跳出當前虛擬環境
設定gunicorn
建立gunicorn.socket
1
| sudo vim /etc/systemd/system/gunicorn.socket
|
檔案寫入
1 2 3 4 5 6 7 8
| [Unit] Description=gunicorn socket
[Socket] ListenStream=/run/gunicorn.sock
[Install] WantedBy=sockets.target
|
寫完上述程式碼後儲存離開ESC
+:wq!
確認一下gunicorn的位置,因為後續建立gunicorn.service
檔時會使用到
執行上述指令會回傳gunicorn的路徑
建立gunicorn.service
1
| sudo vim /etc/systemd/system/gunicorn.service
|
gunicorn.service
檔案寫入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| [Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target
[Service] User=<youruser> Group=www-data WorkingDirectory=<path/to/yourprojectdir> ExecStart=<gunicorn_path> \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ <yourproject>.wsgi:application
[Install] WantedBy=multi-user.target
|
寫完上述程式碼後儲存離開ESC
+:wq!
啟用 Gunicorn socket
1 2
| sudo systemctl start gunicorn.socket sudo systemctl enable gunicorn.socket
|
檢查Gunicorn socket是否運作成功
1
| sudo systemctl status gunicorn.socket
|
成功會顯示綠色active
字樣
檢查gunicorn.sock 檔案是否存在/run
這個資料夾中
如果發現沒有在/run
這個資料夾中,或是有其他問題,可以執行下方指令查看Log找問題
1
| sudo journalctl -u gunicorn.socket
|
測試Server運作情況
1
| sudo systemctl status gunicorn
|
或是發Curl
測試
1
| curl --unix-socket /run/gunicorn.sock localhost
|
回傳結果為HTML格式的資料
要對gunicorn排查問題也可以執行下方指令看Log
1
| sudo journalctl -u gunicorn
|
若遇到問題,且查看Log後將問題排除,需要再重新run一次gunicorn
1 2
| sudo systemctl daemon-reload sudo systemctl restart gunicorn
|
配置Nginx代理傳給Gunicorn
1
| sudo vim /etc/nginx/sites-available/project_name.conf
|
project_name
修改為專案名稱
project_name.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server { listen 80; server_name <domain_name> <server_ip>;
location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root <your_static_root_path>; }
location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; } }
|
將檔案連結到啟動網站的目錄來啟動該檔案
1 2 3
| sudo ln -s /etc/nginx/sites-available/project_name.conf /etc/nginx/sites-enabled sudo nginx -t sudo systemctl restart nginx
|
設防火牆需要開放80 port上的流量,並刪除8000 port,禁止訪問。
1 2
| sudo ufw delete allow 8000 sudo ufw allow 'Nginx Full'
|
建立成功!